package web.admin.shop.product.tabs;


import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.markup.html.tree.ITreeState;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import service.facade.admin.ShopAdminService;
import web.admin.shop.product.checkboxtree.CategoryTreeModel;
import web.admin.shop.product.checkboxtree.CategoryTreeNode;
import web.admin.shop.product.checkboxtree.CategoryTreeState;
import web.admin.shop.product.checkboxtree.CheckBoxTree;

import javax.swing.tree.TreeNode;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ProductCategoriesPanel extends Panel {

    private BaseTree categoryTree;
    private CategoryTreeModel treeModel;
    @SpringBean
    ShopAdminService shopAdminService;
    private Long productId;
    private Map<Long, Boolean> myState;
    private Set<Long> productCategoryIds;
    private static Logger logger = Logger.getLogger(ProductCategoriesPanel.class.getName());

    public ProductCategoriesPanel(String id, final Long productId) {
        super(id);
        this.productId = productId;
        myState = new HashMap<Long, Boolean>();
        treeModel = new CategoryTreeModel();
        Form form = new Form("form") {
            {
                add(new Button("save") {
                    @Override
                    public void onSubmit() {
                        try {
                            shopAdminService.setProductToCategories(productId, myState);
                            info(getLocalizer().getString("saved", this));
                        } catch (Exception e) {
                            logger.log(Level.SEVERE, null, e);
                            error(getLocalizer().getString("system.error", this));
                        }
                    }
                });
            }
        };
        form.add(categoryTree = new CheckBoxTree("categoryTree", treeModel) {

            {
            }

            @Override
            protected ITreeState newTreeState() {
                CategoryTreeState state = new CategoryTreeState() {

                    public boolean isNodeSelected(TreeNode node) {

                        return isSelected(node);
                    }

                    @Override
                    public void selectNode(TreeNode node, boolean select) {
                    }
                };
                state.setAllowSelectMultiple(false);
                state.expandAll();
                return state;
            }

            @Override
            public IModel newCheckBoxModel(final TreeNode tnode) {
                return new IModel() {

                    public Object getObject() {
                        return getProductCategoryIds().contains(getCategoryId(tnode))
                                ? Boolean.TRUE : Boolean.FALSE;
                    }

                    public void setObject(Object object) {
                    }

                    public void detach() {
                    }
                };
            }

            @Override
            protected void onNodeCheckUpdated(TreeNode node, BaseTree tree,
                                              AjaxRequestTarget target) {

                if (productCategoryIds.contains(getCategoryId(node))) {
                    try {
                        getProductCategoryIds().remove(getCategoryId(node));
                        myState.put(getCategoryId(node), false);
                    } catch (Exception e) {
                        error(e);
                    }
                } else {
                    try {
                        getProductCategoryIds().add(getCategoryId(node));
                        myState.put(getCategoryId(node), true);
                    } catch (Exception e) {
                        error(e);
                    }
                }
                target.addComponent(tree);

            }
        });
        categoryTree.setRootLess(true);
        categoryTree.setOutputMarkupId(true);
        add(form);
    }

    private boolean isSelected(TreeNode tnode) {
        return getProductCategoryIds().contains(getCategoryId(tnode));
    }

    private Long getCategoryId(TreeNode tnode) {
        Long id = null;

        if (tnode instanceof CategoryTreeNode) {
            id = ((CategoryTreeNode) tnode).getCategoryId();
        }
        return id;
    }

    private void deselectTree(BaseTree tree, TreeNode node) {
        Enumeration nodeEnum = node.children();
        while (nodeEnum.hasMoreElements()) {
            TreeNode child = (TreeNode) nodeEnum.nextElement();
            tree.getTreeState().selectNode(child, false);
            deselectTree(tree, child);
        }
    }

    private List<Long> getCategoryIdTree(TreeNode node) {
        List<Long> ids = new ArrayList<Long>();
        while (node != null) {
            if (node instanceof CategoryTreeNode) {
                CategoryTreeNode catNode = (CategoryTreeNode) node;
                ids.add(0, catNode.getCategoryId());
            }
            node = node.getParent();
        }
        return ids;
    }

    private Set<Long> getProductCategoryIds() {

        if (productCategoryIds == null) {
            productCategoryIds = new HashSet<Long>();
            try {
                productCategoryIds = shopAdminService.getCategoryIdsByProduct(productId);
            } catch (Exception e) {
                error(e);
            }
        }
        return productCategoryIds;
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

}
